package com.wosiliujing.learning.gateway.writer;

import com.wosiliujing.learning.constant.CacheConstants;
import com.wosiliujing.learning.gateway.vo.RouteDefinitionVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

/**
 * @author liujing
 * @Description: TODO
 * @date 2019/6/3015:26
 */
@Slf4j
@Component
@AllArgsConstructor
public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {

    private final RedisTemplate redisTemplate;

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(RouteDefinitionVo.class));
        List<RouteDefinitionVo> routeDefinitionVos = redisTemplate.opsForHash().values(CacheConstants.ROUTE_KEY);
        List<RouteDefinition> routes = new ArrayList<>();
        routeDefinitionVos.forEach(routeDefinitionVo -> {
            RouteDefinition  routeDefinition = new RouteDefinition();
            BeanUtils.copyProperties(routeDefinitionVo, routeDefinition);
            routes.add(routeDefinition);
        });
        return Flux.fromIterable(routes);
    }

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(r -> {
            RouteDefinitionVo routeDefinitionVo = new RouteDefinitionVo();
            BeanUtils.copyProperties(r,routeDefinitionVo);
            log.info("保存路由信息:{}", routeDefinitionVo);
            redisTemplate.setKeySerializer(new StringRedisSerializer());
            redisTemplate.opsForHash().put(CacheConstants.ROUTE_KEY, routeDefinitionVo.getId(),routeDefinitionVo);
            return  Mono.empty();
        });
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        routeId.subscribe(id -> {
            log.info("删除路由id:{}", id);
            redisTemplate.setKeySerializer(new StringRedisSerializer());
            redisTemplate.opsForHash().delete(CacheConstants.ROUTE_KEY,id);
        });
        return Mono.empty();
    }
}
